﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aga.GestionDeArchivos.Domain.Entities;
using AutoMapper;
using Aga.GestionDeArchivos.Storage;
using Aga.GestionDeArchivos.Common;

namespace Aga.GestionDeArchivos.Services
{
    public class RoleService : DomainServiceBase<Role>
    {
        protected override RepositoryBase<Role> Repository
        {
            get { return RepositoryFactory.CreateRoleRepository(); }
        }

        public PagedList<Role> GetPage(int pageIndex, int pageSize)
        {
            var items = GetAll().OrderBy(c => c.Name).Skip(pageIndex * pageSize).Take(pageSize).ToList();

            int totalCount = GetAll().Count();
            int pageCount = Convert.ToInt32(Math.Ceiling((double)totalCount / pageSize));

            return new PagedList<Role>(items, pageIndex, pageCount, pageSize, totalCount);
        }

        /// <summary>
        /// Adds the new role.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="description">The description.</param>
        /// <returns></returns>
        public Role AddNewRole(string name, string description)
        {
            Role role = new Role
            {
                Name = name,
                Description = description,
            };

            RoleAction defaultAction = new RoleAction
            {
                Role = role,
                ActionId = (int)Actions.None 
            };

            role.Actions.Add(defaultAction);

            return Save(role);
        }

        /// <summary>
        /// Adds the actions.
        /// </summary>
        /// <param name="roleId">The role id.</param>
        /// <param name="actionsIds">The actions ids.</param>
        /// <returns></returns>
        public Role AddActions(int roleId, int[] actionsIds)
        {
            Role role = RepositoryFactory.CreateRoleRepository().AddActionsToRole(roleId, actionsIds);

            return role;
        }

        /// <summary>
        /// Removes the actions.
        /// </summary>
        /// <param name="roleId">The role id.</param>
        /// <param name="actionsIds">The actions ids.</param>
        /// <returns></returns>
        public Role RemoveActions(int roleId, int[] actionsIds)
        {
            Role role = RepositoryFactory.CreateRoleRepository().RemoveActionsFromRole(roleId, actionsIds);

            return role;
        }

        /// <summary>
        /// Updates the actions.
        /// </summary>
        /// <param name="roleId">The role id.</param>
        /// <param name="actions">The actions.</param>
        public void UpdateActions(int roleId, List<int> actions)
        {
            var role = RepositoryFactory.CreateRoleRepository().GetById(roleId);

            var actionsToRemove = (from a in role.Actions
                                   where !actions.Contains(a.ActionId)
                                   select a.ActionId).ToArray();

            var actionsToAdd = (from a in actions
                                where !role.Actions.Any(action => action.ActionId.Equals(a))
                                select a).ToArray();

            RepositoryFactory.CreateRoleRepository().RemoveActionsFromRole(roleId, actionsToRemove);
            RepositoryFactory.CreateRoleRepository().AddActionsToRole(roleId, actionsToAdd);
        }
    }
}
